/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package aptech.eproject.logictics.dao.thinh;

import aptech.eproject.logictics.db.*;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.*;
import javax.annotation.*;
import javax.ejb.*;
import javax.persistence.*;

/**
 *
 * @author HOANGTHINH
 */
@Stateless(name="stateless/DeliveryStatusManage")
@TransactionManagement(value = TransactionManagementType.CONTAINER)
public class DeliveryStatusManage implements DeliveryStatusManageRemote {

    @Resource
    private SessionContext context;
    @PersistenceContext(name = "LogicticsService")
    EntityManager em;

    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")
    /**
     * Get list Full name of customer . Use to load to cust name search box
     * @return
     *  List of type object can be cast to string - c.fullName
     */
    public List getListCustomerName() {
        Query query = em.createQuery("SELECT c.fullName FROM  Customer c WHERE c.isBlocked='false' ");
        return query.getResultList();

    }

    /**
     * get list delivery of customer name.List delivery contain all package have diference various status
     * to get all delivery pass null
     * @param custName - Full Name of Customer
     * @return
     *     list delivery
     */
    public List getListDeliveryByCustName(String custName) {
        //List delivery contain all package have diference various status
        List lstDeliveryNotAtDesBranch = new ArrayList<Delivery>();
        Query query = null;
        String qlDelivery = "SELECT d From Delivery d WHERE d.isDeleted='False'";
        if (custName != null) {
            custName = "%" + custName + "%";
            qlDelivery ="SELECT d FROM Delivery d JOIN d.consigner c WHERE c.fullName Like ?1 AND d.isDeleted='False'";
            query = em.createQuery(qlDelivery);
            query.setParameter(1, custName);
        }
        else
        {
            query = em.createQuery(qlDelivery);
        }
        List lstDelivery = query.getResultList();
        for (int i = 0; i < lstDelivery.size(); i++) {
            Delivery d = (Delivery) lstDelivery.get(i);
           Iterator<aptech.eproject.logictics.db.Package> lstPackages = d.getPackages().iterator();
            // Use to test if delivery contain all package have status delivering or not
            boolean isDelivering = false;
            while(lstPackages.hasNext())
            {
                if (!(lstPackages.next().getDeliveryStatus().equals(DeliveryStatus.Delivering))) {
                    isDelivering = true;
                }
            }
            if (isDelivering) {
                lstDeliveryNotAtDesBranch.add(d);
            }
        }
        return lstDeliveryNotAtDesBranch;
    }

    /**
     * get list delivery of customer name. This delivery contain only package have status is delivering
     * to get all delivery pass null
     * @param custName - Full Name of Customer
     * @return
     *     list delivery
     */
    public List getListDeliveryInDesBranchByCustName(String custName) {
        List lstDeliveryAtDesBranch = new ArrayList<Delivery>();
        Query query = null;
        String qlDelivery = "SELECT d From Delivery d WHERE d.isDeleted='False'";
        if (custName != null) {
            custName = "%" + custName + "%";
            qlDelivery = "SELECT d FROM Delivery d JOIN d.consigner c WHERE c.fullName Like ?1 AND d.isDeleted='False'";
       query = em.createQuery(qlDelivery);
            query.setParameter(1, custName);
        }
        else
        {
            query = em.createQuery(qlDelivery);
        }
     
        List lstDelivery = query.getResultList();
       // System.out.println("Size delivery : "+lstDelivery.size());
        for (int i = 0; i < lstDelivery.size(); i++) {
            Delivery d = (Delivery) lstDelivery.get(i);
            Iterator<aptech.eproject.logictics.db.Package> lstPackages = d.getPackages().iterator();
         //   System.out.println("Size : "+d.getPackages().size());
            // Use to test if delivery contain all package have status delivering or not
            boolean isDelivering = true;
            while(lstPackages.hasNext()){
                aptech.eproject.logictics.db.Package p=lstPackages.next();
              //  System.out.println(p.getDeliveryStatus().toString());
                if (!(p.getDeliveryStatus().equals(DeliveryStatus.Delivering))) {
                    isDelivering = false;
                }
            }
            if (isDelivering) {
                lstDeliveryAtDesBranch.add(d);
            }
        }
        return lstDeliveryAtDesBranch;
    }

    /**
     * Change all status of sub package in delivery to finished
     * Update status of warehouse(branch cuoi) store these package to removed
     * @param deliveryId
     * @return
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public boolean changeDeliveryStatus(int deliveryId) {
        try {
            
            Delivery delivery = em.find(Delivery.class, deliveryId);
             List lst = getListDeliveryInDesBranchByCustName(null);
           if(delivery != null && lst.contains(delivery))
            {
               //System.out.println("Update status of delivery : " +deliveryId);
                Iterator<aptech.eproject.logictics.db.Package> lstPackages =
                       delivery.getPackages().iterator();
                int branchId = delivery.getDestinationBranch().getBranchId();
              //  System.out.println("Delivery contain : "+delivery.getPackages().size()+" package!!");
             //   System.out.println("Package Id: ");
                while (lstPackages.hasNext()) {
                    aptech.eproject.logictics.db.Package p  = lstPackages.next();
                    System.out.print(p.getPackageId());
                      p.setDeliveryStatus(DeliveryStatus.Finished);
                    em.merge(p);
                    // Set status IsRemoved=true of warehouse store these package
                   // System.out.println("\tWarehouse Id : "+branchId);
                    WarehousePK wpk = new WarehousePK(branchId, p.getPackageId());
                    Warehouse warehouse = em.find(Warehouse.class, wpk);
                    if(warehouse!=null)
                    {
                        warehouse.setIsRemoved(true);
                        em.merge(warehouse);
                    }
                    else
                    {
                        warehouse =new Warehouse(wpk,true);
                        em.persist(warehouse);
                    }
                }
                Date d=new Date();
                delivery.setDeliveryDate(new Timestamp(d.getTime()));
                delivery.setIsFinished(true);
                return true;
            }
            else
            {
               // System.err.println("Delivery Not in Des branch");
                return false;
            }
        } catch (NullPointerException npe) {
            npe.printStackTrace();
            context.setRollbackOnly();
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            context.setRollbackOnly();
            return false;
        }
    }

    public String getMessage(List deliveryIds) {
         String str = "";
        for(int i = 0; i < deliveryIds.size(); i++)
        {
            Integer deliveryId = (Integer)deliveryIds.get(i);
            Delivery d = (Delivery)em.find(Delivery.class, deliveryId);
            str += "\n\t Delivery : "+d.getTrackingCode();
        }

        //System.out.println(str);
        return str;
    }

    public Delivery getDelivery(int deliveryId) {
      //  System.out.println("Delivery : "+deliveryId);
              return (Delivery)em.find(Delivery.class, Integer.valueOf(deliveryId));
    }
}
